-------Rosie the Counting Rabbit-------
A 4am crack                  2016-08-23
---------------------------------------

Name: Rosie the Counting Rabbit
Genre: educational
Year: 1987
Authors: Rob Shaver, Peter Andrews
Publisher: D.C. Heath and Company
Media: single-sided 5.25-inch floppy
OS: ProDOS 1.8
Previous cracks: none
Similar cracks:
  #202 Squeegee Learns About Drugs
       (spoiler: they're bad, mmkay)

                   ~

               Chapter 0
 In Which Various Automated Tools Fail
          In Interesting Ways


COPYA
  no read errors, but copy loads ProDOS
  then hangs with drive motor on

Locksmith Fast Disk Backup
  ditto

EDD 4 bit copy (no sync, no count)
  ditto

Copy ][+ nibble editor
  nothing suspicious

Disk Fixer
  T00 -> looks like ProDOS bootloader
  and disk catalog

Why didn't any of my copies work?
  probably a nibble check in the first
  SYSTEM file

Next steps:

  1. trace first .SYSTEM file
  2. disable protection check
  3. I don't know, go feed the ducks or
     something?

                   ~

               Chapter 1
        In Which Things Are Not
         Always As They Appear


[S7,D1=my ProDOS hard drive]
[S6,D1=non-working copy]

]PR#7
]CAT,S6,D1

/EXPLORE

 NAME           TYPE  BLOCKS  MODIFIED

*PRODOS          SYS      32  29-JAN-87
 DISK            BIN       4  30-JAN-87
 FLIPS           DIR       1  30-JAN-87
 ICONS           DIR       1  30-JAN-87
 AUXLOW          BIN       8  30-JAN-87
 AUX.48          BIN      22  30-JAN-87
 AUX.LC          BIN      25  30-JAN-87
 SETUP           BIN       1  30-JAN-87
 MEMORY.CONFIG   SYS       9  <NO DATE>
 STORY.SYSTEM    SYS       3  30-JAN-87
 TITLE.SCREEN    BIN      12  30-JAN-87
 WORDS           DIR       1  30-JAN-87
 P.COUNT.7       DIR       2  30-JAN-87
 COLOR.DATA      BIN       7  30-JAN-87

BLOCKS FREE:   58     BLOCKS USED:  222

]PREFIX /EXPLORE
]-STORY.SYSTEM
...loads and runs(!)...

Wait, what?

It's looking more and more likely that
the nibble check is inside the PRODOS
file itself.

Instead of tracing the entire PRODOS
file, I turn to my trusty Disk Fixer
sector editor and searched for the hex
sequence "BD 89 C0". Although there are
many variations of copy protection, a
surprising number of disks use a nibble
check that starts by loading the X
register with the slot number (x16) and
an "LDA $C089,X" instruction to turn on
the drive motor.

And I get lucky: four matches.

 - T00,S0E - part of the ProDOS
   bootloader (expected)

 - T05,S0D - Copy II Plus disk map says
   this is part of the PRODOS file, but
   I looked and it's part of the RWTS.
   So this is expected and legitimate,
   not the start of a nibble check.

 - T18,S00
 - T18,S0F - both highly suspicious

Copy II Plus disk map says track $18 is
part of the MEMORY.CONFIG file. It's a
SYS file, which means it's probably
loaded at $2000.

]PR#7
...
]PREFIX /EXPLORE
]BLOAD MEMORY.CONFIG,A$2000,TSYS
]CALL -151

*2000L

2000-   20 20 21    JSR   $2120

*2120L

2120-   20 DA 20    JSR   $20DA
2123-   8D F4 03    STA   $03F4
2126-   60          RTS

*20DAL

20DA-   A9 18       LDA   #$18
20DC-   8D 78 04    STA   $0478
20DF-   A9 30       LDA   #$30
20E1-   8D 7E 04    STA   $047E
20E4-   A9 23       LDA   #$23
20E6-   8D EC 27    STA   $27EC
20E9-   A0 00       LDY   #$00
20EB-   98          TYA
20EC-   99 00 BA    STA   $BA00,Y
20EF-   C8          INY
20F0-   D0 FA       BNE   $20EC
20F2-   60          RTS

Not sure yet what's going on.

                   ~

               Chapter 2
         A Fish Out Of ProDOS


Continuing from $2003...

2003-   EA          NOP
2004-   EA          NOP
2005-   A9 00       LDA   #$00
2007-   85 04       STA   $04
2009-   8D F4 27    STA   $27F4
200C-   8D EB 27    STA   $27EB
200F-   A9 27       LDA   #$27
2011-   A0 E8       LDY   #$E8
2013-   20 B5 27    JSR   $27B5

Weird. We're under ProDOS, but this is
all using DOS 3.3-shaped RWTS commands.
(Not shown, but $27B5 calls $2D00 in
exactly the same way that $B7B5 calls
$BD00 in DOS 3.3.) Whatever this file
is, it's designed to be entirely self-
contained. It doesn't use ProDOS at
all.

Anyway, if $27E8 is a DOS 3.3-style
RWTS parameter table, that means that
$27EC (which we set earlier, at $20E6)
is the track number. Which means we're
seeking to track $23 to do... something
protection-related, I bet.

Continuing from $2016...

2016-   A9 00       LDA   #$00
2018-   85 48       STA   $48

; turn on drive motor manually
201A-   BD 89 C0    LDA   $C089,X
201D-   BD 8E C0    LDA   $C08E,X

; looks for the next address field
; (not shown, but identical to $B944
; routine in DOS 3.3)
2020-   20 44 29    JSR   $2944

; is this the sector we wanted?
2023-   A5 2D       LDA   $2D
2025-   C5 04       CMP   $04

; nope, loop back until we find it
2027-   D0 F7       BNE   $2020

; skip to sync byte (#$FF)
2029-   BD 8E C0    LDA   $C08E,X
202C-   BD 8C C0    LDA   $C08C,X
202F-   10 FB       BPL   $202C
2031-   C9 FF       CMP   #$FF
2033-   D0 F4       BNE   $2029

; skip an exact number of nibbles and
; look for #$D5
2035-   A0 00       LDY   #$00
2037-   C8          INY
2038-   BD 8E C0    LDA   $C08E,X
203B-   BD 8C C0    LDA   $C08C,X
203E-   10 FB       BPL   $203B
2040-   C9 D5       CMP   #$D5

; if not found in correct location, try
; again from the top
2042-   D0 F3       BNE   $2037
2044-   C0 07       CPY   #$07
2046-   D0 B8       BNE   $2000

; do this for all sectors
2048-   E6 04       INC   $04
204A-   A9 10       LDA   #$10
204C-   C5 04       CMP   $04
204E-   D0 D0       BNE   $2020

; start over on sector 0
2050-   A9 00       LDA   #$00
2052-   85 04       STA   $04
2054-   20 44 29    JSR   $2944
2057-   A5 2D       LDA   $2D
2059-   C5 04       CMP   $04
205B-   D0 F7       BNE   $2054

; skip to address epilogue
205D-   BD 8C C0    LDA   $C08C,X
2060-   10 FB       BPL   $205D
2062-   C9 AA       CMP   #$AA
2064-   D0 F7       BNE   $205D
2066-   BD 8C C0    LDA   $C08C,X
2069-   10 FB       BPL   $2066
206B-   C9 EB       CMP   #$EB
206D-   D0 EE       BNE   $205D

; skip to sync byte (#$FF)
206F-   BD 8C C0    LDA   $C08C,X
2072-   10 FB       BPL   $206F
2074-   C9 FF       CMP   #$FF
2076-   D0 F7       BNE   $206F

; skip an exact number of nibbles and
; look for #$D5
2078-   A0 00       LDY   #$00
207A-   C8          INY
207B-   BD 8E C0    LDA   $C08E,X
207E-   BD 8C C0    LDA   $C08C,X
2081-   10 FB       BPL   $207E
2083-   C9 D5       CMP   #$D5

; if not found in correct location, try
; again from the top
2085-   D0 F3       BNE   $207A
2087-   C0 10       CPY   #$10
2089-   D0 C5       BNE   $2050

; do this for several other sectors
208B-   E6 04       INC   $04
208D-   A9 0A       LDA   #$0A
208F-   20 00 21    JSR   $2100
2092-   A9 04       LDA   #$04
2094-   C5 04       CMP   $04
2096-   D0 04       BNE   $209C
2098-   E6 04       INC   $04
209A-   D0 B8       BNE   $2054
209C-   A9 0F       LDA   #$0F
209E-   C5 04       CMP   $04
20A0-   D0 BB       BNE   $205D
20A2-   20 44 29    JSR   $2944
20A5-   A5 2D       LDA   $2D
20A7-   C9 0F       CMP   #$0F
20A9-   D0 F7       BNE   $20A2

; read data field (not shown)
20AB-   20 DC 28    JSR   $28DC

; look for #$A5 nibble in a specific
; place
20AE-   A0 00       LDY   #$00
20B0-   C8          INY
20B1-   BD 8E C0    LDA   $C08E,X
20B4-   BD 8C C0    LDA   $C08C,X
20B7-   10 FB       BPL   $20B4
20B9-   C9 A5       CMP   #$A5
20BB-   D0 F3       BNE   $20B0
20BD-   C0 2B       CPY   #$2B
20BF-   D0 E1       BNE   $20A2

; look for #$D5 nibble in a specific
; place
20C1-   A0 00       LDY   #$00
20C3-   C8          INY
20C4-   BD 8E C0    LDA   $C08E,X
20C7-   BD 8C C0    LDA   $C08C,X
20CA-   10 FB       BPL   $20C7
20CC-   C9 D5       CMP   #$D5
20CE-   D0 F3       BNE   $20C3
20D0-   C0 5D       CPY   #$5D
20D2-   D0 CE       BNE   $20A2

; success path falls through to here
20D4-   A0 00       LDY   #$00
20D6-   EA          NOP
20D7-   4C F3 20    JMP   $20F3

My copy never makes it this far. It's
stuck in an infinite loop, trying to
find a precisely organized track $23
(and failing).

It looks like I should be able to skip
over the protection check by jumping
straight to the success path at $20D4.

T18,S00,$00: 202021 -> 4CD420

]PR#6
...works...

Quod erat liberandum.

                   ~

               Epilogue


The program runs when I execute
STORY.SYSTEM directly. So how does
MEMORY.CONFIG get called?

Disk Fixer
  --> [F]ind
    --> [A]SCII
      --> "CONFIG"

                 --v--

-------------- DISK EDIT --------------
TRACK $01/SECTOR $01/VOLUME $FE/BYTE$E8
---------------------------------------
$80: CD A2 A0 C6 C9 CC C5 A0   M" FILE
$88: A0 AA AA A0 AA AA A0 A0    ** **
$90: D3 D9 D3 D4 C5 CD A0 D0   SYSTEM P
$98: D2 CF C7 D2 C1 CD A0 D4   ROGRAM T
$A0: CF CF A0 CC C1 D2 C7 C5   OO LARGE
$A8: A0 A0 AA AA AA AA A0 D5     **** U
$B0: CE C1 C2 CC C5 A0 D4 CF   NABLE TO
$B8: A0 CC CF C1 C4 A0 D8 AE    LOAD X.
$C0: D3 D9 D3 D4 C5 CD A0 AA   SYSTEM *
$C8: AA AA AA AA AA AA AA AA   ********
$D0: AA 00 03 80 02 00 14 01   *@C.B@TA
$D8: 02 01 00 00 00 04 01 00   BA@@@DA@
$E0: 20 00 00 00 00 01 00 AE    @@@@A@.
$E8:>C3<CF CE C6 C9 C7 8D 08   CONFIG.H
     ^^^^^^^^^^^^^^^^^
  this should be "SYSTEM"

$F0: C0 B5 42 8D 09 C0 95 42   @5B.I@.B
$F8: CA 10 F3 A9 28 38 8D 08   JPs)(8.H
---------------------------------------
BUFFER 0/SLOT 6/DRIVE 1/MASK OFF/NORMAL

---------------------------------------
COMMAND : _

                 --^--

And there it is: a hacked version of
PRODOS that, instead of looking for the
first .SYSTEM file, looks for the first
.CONFIG file. Of course there's only
one of those, MEMORY.CONFIG, which
silently performs its nibble check
before manually reading STORY.SYSTEM
and jumping to it.

---------------------------------------
A 4am crack                     No. 811
------------------EOF------------------
